#include "glwidget.h"

void GLWidget::AddCurve( Curve* _curve, QColor _curveColor,
                         QColor _pointsColor )
{
    m_curves.push_back( _curve );
    m_curveColor.push_back( _curveColor );
    m_pointsColor.push_back( _pointsColor );
}

void GLWidget::initializeGL( )
{
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_BLEND );
    glEnable( GL_LINE_SMOOTH );
    glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
    glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
}

void GLWidget::resizeGL( int _width, int _height )
{
    glViewport( 0, 0, (GLint)_width, (GLint)_height );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );
    gluOrtho2D( 0.0, 500.0, 0.0, 500.0 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );
}

void GLWidget::paintGL( )
{
    glClear( GL_COLOR_BUFFER_BIT );
    glLoadIdentity( );

    draw( );

    glFlush( );
}

void GLWidget::draw( )
{
    for ( unsigned int i = 0; i < m_curves.size( ); ++i )
    {
        DrawCurve( *m_curves[i], m_curveColor[i] );
        DrawControlPoints( *m_curves[i], m_pointsColor[i] );
    }
}

void GLWidget::DrawCurve( Curve& _icurve, QColor _color )
{
    float x, y;

    Vector computedPoints = _icurve.GetCurvePoints( );
    int numberOfPoints    = computedPoints.size( );

    glColor3f( _color.redF(), _color.greenF(), _color.blueF() );
    glLineWidth( 2.0 );

    glBegin( GL_LINE_STRIP );
//    glBegin( GL_POINTS );
//    glBegin( GL_LINE_LOOP );
        // Rysujemy krzywa
        for ( int i = 0; i < numberOfPoints; i++ )
        {
            x = (GLfloat)computedPoints[i].x( );
            y = (GLfloat)computedPoints[i].y( );

            glVertex2f( x, y );
        }
    glEnd( );
}

void GLWidget::DrawControlPoints( const Curve& _icurve, QColor _color )
{
    float x, y;
    Vector control_points = _icurve.GetControlPoints( );

    glColor3f( _color.redF(), _color.greenF(), _color.blueF() );
    glBegin( GL_POINT );
        // Rysujemy punkty kontrolne.
        for ( unsigned int i = 0; i < control_points.size( ); i++ )
        {

            x = (GLfloat)control_points[i].x( );
            y = (GLfloat)control_points[i].y( );

            GLWidget::DrawControlPoint( (GLint)x, (GLint)y, (GLint)2, _color );
        }
    glEnd( );
}

void GLWidget::DrawControlPoint( GLint _x, GLint _y, GLint _radius, QColor _color )
{
    float angle;

    glPushMatrix( );
    glLoadIdentity( );

    glColor3f( _color.redF(), _color.greenF(), _color.blueF() );
    glLineWidth( 2.0f );

    glBegin( GL_POLYGON );
        for ( int i = 0; i < 100; i++ )
        {
            angle = i * 2.0 * M_PI / 100.0;
            glVertex2f( _x + (cos( angle ) * _radius), _y + (sin( angle ) * _radius) );
        }
    glEnd( );

    glPopMatrix( );
}
